package com.xplay.xpocker.room.mahjong.action;

import com.xplay.xpocker.constant.MessageNoticeEnum;
import com.xplay.xpocker.dvo.GameRuMahjongUserState;
import com.xplay.xpocker.dvo.AbstractRoom;
import com.xplay.xpocker.entity.GameRuMahjongLogs;
import com.xplay.xpocker.room.RoomInfoTL;
import com.xplay.xpocker.room.mahjong.AbstractIsolationEventStrategy;
import com.xplay.xpocker.room.mahjong.AbstractMahjongMessageStrategy;
import com.xplay.xpocker.room.mahjong.MahjongConfigProp;
import com.xplay.xpocker.room.mahjong.constant.MKey;
import com.xplay.xpocker.room.mahjong.dto.*;
import com.xplay.xpocker.room.message.MessageContent;
import com.xplay.xpocker.room.message.MessageContentFactory;
import com.xplay.xpocker.room.message.MessageToClient;
import com.xplay.xpocker.room.message.MessageType;
import com.xplay.xpocker.util.Assertion;
import com.xplay.xpocker.util.CardUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Random;

@Slf4j
@Service
public class ExchangeAction extends AbstractMahjongMessageStrategy<AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs>, MahjongMessage> {


    @Override
    protected String strategyName() {
        return MahjongActionEnum.EXCHANGE.getAction();
    }

    // TODO 碰牌需要判断有没有人要胡牌 杠牌优先级低于胡牌
    @Override
    public boolean doMessage(AbstractRoom<MahjongRoomRule, MahjongRoomInfo, GameRuMahjongLogs> roomInfo, MahjongMessage messageInfo) {

        GameRuMahjongUserState currentUser = roomInfo.getGameInfo().getCurrentUser();
        currentUser.setSwapCardOut(CardUtil.joinCard(messageInfo.getSwapCard()));
        Assertion.isTrue(messageInfo.getSwapCard() == null || messageInfo.getSwapCard().size() != 3, "卡牌信息有误,请重新拿出");
        if (!roomInfo.getRule().checkExistsRule(WzRuleEnum.MP.getCode())) {
            Assertion.isTrue(CardUtil.judgeUserCardClass(messageInfo.getSwapCard()) > 1, "未开启买牌,请拿出同色卡牌");
        }
        log.debug("房间号:{},用户：{},拿出换牌信息：{}", roomInfo.getCode(), currentUser.getUsername(), messageInfo.getSwapCard());
        currentUser.removeCard(messageInfo.getSwapCard());
        //通知所有人 我拿牌出来了
        int userCount = roomInfo.getRule().getUserCount();


        List<MessageContent<MessageToClient>> messageList = MessageContentFactory.
                init(roomInfo.getCode(), MessageType.ACTION.getType(),
                        currentUser.getUserId(), MessageNoticeEnum.CURRENT)
                .multi(MKey.exeActionUid, currentUser.getUserId(),
                        MKey.type, MahjongActionEnum.EXCHANGE.getAction(),
                        MKey.swapCard, messageInfo.getSwapCard()).send()
                // 其它人过滤掉卡牌
                .filter(MessageNoticeEnum.OTHER, MahjongConfigProp.getInstance().isDesensitize() ? MKey.swapCard : null)
                .send().getMessageList();
        RoomInfoTL.addMessageToClient(messageList);

        //  当最后一个用户拿出交换牌的时候,通知
        if (!checkExistsWaitCompleted()) {
            int one = new Random().nextInt(6) + 1;
            int two = new Random().nextInt(6) + 1;
            if (userCount == 2) {
                swapCard(1, 2);
                swapCard(2, 1);
            } else if (userCount == 3) {
                int remainder = one % userCount;
                int addNumber = remainder == 0 ? userCount - 1 : remainder - 1;
                switch (addNumber) {
                    //顺时针
                    case 0:
                        swapCard(1, 2);
                        swapCard(2, 3);
                        swapCard(3, 1);
                        break;
                    case 1:
                        swapCard(1, 3);
                        swapCard(2, 1);
                        swapCard(3, 2);
                        break;
                }
            } else if (userCount == 4) {
                int remainder = (one + two) % userCount;
                int addNumber = remainder == 0 ? userCount - 1 : remainder - 1;
                switch (addNumber) {
                    //对家
                    case 0:
                    case 2:
                        swapCard(1, 3);
                        swapCard(3, 1);
                        swapCard(2, 4);
                        swapCard(4, 2);
                        break;
                    //顺时针
                    case 1:
                        swapCard(1, 4);
                        swapCard(2, 1);
                        swapCard(3, 2);
                        swapCard(4, 3);
                        break;
                    //顺时针
                    case 3:
                        swapCard(1, 2);
                        swapCard(2, 3);
                        swapCard(3, 4);
                        swapCard(4, 1);
                        break;
                }
            }
            // 当产生交换完毕 将用户得到的卡牌  和 骰子信息一起传递给前端
            for (GameRuMahjongUserState user : roomInfo.getGameInfo().getAllUser()) {
                List<MessageContent<MessageToClient>> diceMessage = MessageContentFactory.
                        init(roomInfo.getCode(), MessageType.ACTION.getType(), user.getUserId(), MessageNoticeEnum.CURRENT)
                        .multi(MKey.exeActionUid, user.getUserId(),
                                MKey.type, MahjongActionEnum.DICE.getAction(),
                                MKey.data, String.format("%s,%s", one, two),
                                MKey.swapCard, CardUtil.buildCardList(user.getSwapCardIn())).send().getMessageList();
                RoomInfoTL.addMessageToClient(diceMessage, 0.5);
            }
            // 换牌后 不同类型的 需要做不同类型的处理
            AbstractIsolationEventStrategy.getSettlementStrategy(roomInfo.getType()).gameStartActionCheck(roomInfo);

        }
        return true;
    }

    /**
     * @param source 谁
     * @param target 拿谁的牌
     */

    private void swapCard(int source, int target) {
        GameRuMahjongUserState sourceUser = getUserByUidOrSeq(null, source);
        GameRuMahjongUserState targetUser = getUserByUidOrSeq(null, target);
        sourceUser.setSwapUserId(targetUser.getUserId());
        sourceUser.setSwapCardIn(targetUser.getSwapCardOut());
        sourceUser.addCardList(CardUtil.buildCardList(targetUser.getSwapCardOut()));
    }

}
